﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using InspectionMAC.Forms;
using InspectionMAC.Function;
using InspectionMAC.SystemThread;
using InspectionMAC.Config;
using MvCameraControl;
using MvCamCtrl.NET;
using System.Runtime.InteropServices;
using csLTDMC;
using InspectionMAC.Algorithm;
using System.Collections.Concurrent;
using System.Threading;

namespace InspectionMAC
{
    public partial class MainForm : Form
    {
        public static Camera_Form camera_Form;
        public static Multiple_Form multiple_Form;
        public static Param_Form param_Form;

        public static MacTestForm mactest_Form;
        public static MainForm main_Form;

        public  PictureBox[] pictureBoxes = new  PictureBox[3];

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            main_Form = this;

            //Guid uniqueId = Guid.NewGuid();
            //string id = uniqueId.ToString();
            //Console.WriteLine("id:"+ id);
            //GetCameraImgThread01.CameraImgGet_Thread();
            //GetCameraImgThread02.CameraImgGet_Thread();
            //GetCameraImgThread03.CameraImgGet_Thread();

            //GetCameraImgThread101.CameraImgGet_Thread();
            //GetCameraImgThread102.CameraImgGet_Thread();
            //GetCameraImgThread103.CameraImgGet_Thread();

            InitializeDisplayTimer();
            Initial_Card.DMC300_InitialClass();//检测板卡状态
            LocationThread.Location_State();  //--读取相关轴信息
            ///----一開始就啟動一維位置比較功能，並且先強制清除裡面的比較位置值-----------
            LTDMC.dmc_compare_set_config(0, 0, 1, 1);
            LTDMC.dmc_compare_clear_points(0, 0);
            LTDMC.dmc_compare_set_config(0, 1, 1, 1);
            LTDMC.dmc_compare_clear_points(0, 1);
            LTDMC.dmc_compare_set_config(0, 2, 1, 1);
            LTDMC.dmc_compare_clear_points(0, 2);
            ///---------------------------------------------------------------------------

            //传感器状态检测

            //真空及气压状态检测


            DIO_Thread.DIO_State();  //DIO线程启动
            //CameraTriggerThread.CameraTrigger_Thread();//传感器一  相机一二
            //CameraTriggerThread02.CameraTrigger_Thread();//传感器二  相机三
            NG_Control.NG_Flow_Thread();   //NG吹气踢料线程启动

            //DiskSpaceThread.CheckDiskSpace_Thread();//磁盘容量检测

            pictureBoxes[0] = cameraPb_01;
            pictureBoxes[1] = cameraPb_02;
            pictureBoxes[2] = cameraPb_03;
            Console.WriteLine(pictureBoxes[0].Image==null);
            //cameraPb_01.Image = Image.FromFile(Application.StartupPath + "\\Test\\1.jpg");
            cameraPb_01.SizeMode = PictureBoxSizeMode.Zoom;
            cameraPb_01.BackgroundImageLayout = ImageLayout.Zoom;

            //cameraPb_02.Image = Image.FromFile(Application.StartupPath + "\\Test\\First.bmp");
            cameraPb_02.SizeMode = PictureBoxSizeMode.Zoom;

            //cameraPb_03.Image = Image.FromFile(Application.StartupPath + "\\Test\\First.bmp");
            cameraPb_03.SizeMode = PictureBoxSizeMode.Zoom;

            //MultipleParamInit();

            //AlgorithmModule.ImageHandle("Test\\1.jpg");
            ////cameraPb_01.Image = AlgorithmModule.RectPoints(cameraPb_01.Image);
            //DataStorageToExcelThread.Initialize();
            //CameraReceiveThread_01.CameraInitialize();
            //CameraReceiveThread_02.CameraInitialize();//打开相机2
            //CameraReceiveThread_03.CameraInitialize();//打开相机3
            CameraTriggerService.CameraImgGet_Thread();
            TestDioThread.TestDio_Thread();


            AddPointThread01.AddPoint_Thread();
            AddPointThread02.AddPoint_Thread();
            BuilderManager.Initialize();
            StartMaterialMonitor();

        }
        public CameraTriggerService _triggerService;
        private void StartMaterialMonitor()
        {
            var monitorThread = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        Console.WriteLine("\n===== 物料状态监控 [刷新时间: {0:HH:mm:ss}] =====", DateTime.Now);

                        // 1. 队列状态
                        int queueDepth = MaterialTracker.GetQueueDepth();
                        Console.WriteLine($"当前队列深度: {queueDepth}/10");

                        // 2. 状态统计
                        var statusStats = MaterialTracker.GetStatusStatistics();
                        Console.WriteLine("物料状态统计:");
                        foreach (var stat in statusStats)
                        {
                            if (stat.Value > 0)
                            {
                                Console.WriteLine($"  {stat.Key}: {stat.Value}个");
                            }
                        }

                        // 3. 队列中的物料详情
                        var queueMaterials = MaterialTracker.GetQueueSnapshot();
                        if (queueMaterials.Count > 0)
                        {
                            Console.WriteLine("\n队列中的物料:");
                            for (int i = 0; i < queueMaterials.Count; i++)
                            {
                                var material = queueMaterials[i];
                                string position = i == 0 ? "[队首]" : (i == queueMaterials.Count - 1 ? "[队尾]" : "");
                                Console.WriteLine($"  {position} 物料{i + 1}: {material.Id} | " +
                                                 $"状态: {material.Status} | " +
                                                 $"最后更新: {material.LastUpdate:HH:mm:ss}");
                            }
                        }

                        var activeMaterials = MaterialTracker.GetAllActiveMaterials();
                        var nonQueueMaterials = activeMaterials.FindAll(m => !queueMaterials.Contains(m));

                        if (nonQueueMaterials.Count > 0)
                        {
                            Console.WriteLine("\n非队列活跃物料:");
                            foreach (var material in nonQueueMaterials)
                            {
                                Console.WriteLine($"  {material.Id} | " +
                                                 $"状态: {material.Status} | " +
                                                 $"最后更新: {material.LastUpdate:HH:mm:ss}");
                            }
                        }

                        // 5. 分隔线
                        Console.WriteLine(new string('=', 60));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"物料监控异常: {ex.Message}");
                    }

                    Thread.Sleep(30000); // 5秒刷新一次
                }
            })
            {
                IsBackground = true,
                Name = "MaterialMonitorThread"
            };
            monitorThread.Start();
        }
        private void StartBtn_Click(object sender, EventArgs e)
        {
            uint currentPos = LTDMC.dmc_get_encoder(DMC300_Info.usCardId[0], 1);
            uint newPos;
            uint currentPos1 = LTDMC.dmc_get_encoder(DMC300_Info.usCardId[0], 2);
            uint newPos1;
            try
            {
                checked
                {
                    newPos = currentPos + 75262;
                    newPos1 = currentPos1 + 75262;
                }
                LTDMC.dmc_compare_add_point(0, 2, newPos1, 1, 5, 1);
                LTDMC.dmc_compare_add_point(0, 1, newPos+30000, 1, 5, 2);
            }
            catch (OverflowException)
            {
                uint actualPos = unchecked(LTDMC.dmc_get_encoder(DMC300_Info.usCardId[0], 2) + 100000);
                newPos = unchecked(currentPos + 100000);
                LTDMC.dmc_compare_add_point(0, 2, newPos, 1, 5, 10);
                Console.WriteLine("比较点溢位，当前位置"+ LTDMC.dmc_get_encoder(DMC300_Info.usCardId[0], 2));
                Console.WriteLine("添加溢位比较点:" + newPos + ";" + "DO:" + 3 + ";");
            }
            
            

            //DMC300_Info.CameraTrigger_IsStop01 = false;
            //DMC300_Info.CameraTrigger_IsStop02 = false;

            //OpenDevice();

            ////OpenContinuesMode();
            //OpenTriggerMode();
            //StartGrab();

            //CameraTriggerThread.iCameraTrigger_Step = 10;
            //CameraTriggerThread02.iCameraTrigger_Step = 10;d
            //CameraTriggerService.CameraImgGet_Step = 5;
            //StartBtn.Enabled = false;

            StopBtn.Enabled = true;
        }
        private void StopBtn_Click(object sender, EventArgs e)
        {
            TestDioThread.iTestDio_Step = 33;

            //TestDioThread.TestDioFlow_Thread.Join();
            //CameraTriggerService.CameraImgGet_Step = 1;
            //string imagepath = @"Test\10.jpg";

            //CameraResult01 cameraResult = new CameraResult01();
            //AlgorithmModule.ProcessImage1(imagepath, "s1111111", 1, ref cameraResult);
            //string imagepath = @"Test\9.jpg";
            //AlgorithmModule.ImageHandle(imagepath);
            //DMC300_Info.CameraTrigger_IsStop01 = true;
            //DMC300_Info.CameraTrigger_IsStop02 = true;

            //StopGrab();
            //CloseDevice();

            //CameraReceiveThread_01.CloseDevice();
            //CameraReceiveThread_02.CloseDevice();
            //CameraReceiveThread_03.CloseDevice();
            //StartBtn.Enabled = true;
            //StopBtn.Enabled = false;
            //CameraReceiveThread_01.device.Parameters.SetCommandValue("TriggerSoftware");
            //CameraTriggerService.CameraImgGet_Step = 1;
        }
        private void Camera_Btn_Click(object sender, EventArgs e)
        {
            if (camera_Form == null)
            {
                camera_Form = new Camera_Form();
                camera_Form.Show();
            }
            else
            {
                camera_Form.TopMost = true;
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            LTDMC.dmc_compare_clear_points(0, 0);
            LTDMC.dmc_compare_clear_points(0, 2);
            CameraReceiveThread_01.CloseDevice();
            CameraReceiveThread_02.CloseDevice();
            CameraReceiveThread_03.CloseDevice();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            LocationThread.LocationContinuous = false;
            AddOverflowThread.bAddOverflow = false;
            StopGrab();
            CloseDevice();
            // ch: 反初始化SDK | en: Finalize SDK
            MyCamera.MV_CC_Finalize_NET();
            LTDMC.dmc_compare_clear_points(0, 0);
            LTDMC.dmc_compare_clear_points(0, 2);
            CameraReceiveThread_01.CloseDevice();
            CameraReceiveThread_02.CloseDevice();
            CameraReceiveThread_03.CloseDevice();
        }

        private void MultipleCam_Btn_Click(object sender, EventArgs e)
        {
            if (multiple_Form == null)
            {
                multiple_Form = new Multiple_Form();
                multiple_Form.Show();
            }
            else
            {
                multiple_Form.TopMost = true;
            }
        }

        private void Param_Btn_Click(object sender, EventArgs e)
        {
            //if (param_Form == null)
            //{
            //    param_Form = new Param_Form();
            //    param_Form.Show();
            //}
            //else
            //{
            //    param_Form.TopMost = true;
            //}
            if (mactest_Form == null)
            {
                mactest_Form = new MacTestForm();
                mactest_Form.Show();
            }
            else
            {
                mactest_Form.TopMost = true;
            }
        }

        #region Multiple
        [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
        private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

        public UInt32[] m_nSaveImageBufSize = new UInt32[4] { 0, 0, 0, 0 };
        public IntPtr[] m_pSaveImageBuf = new IntPtr[4] { IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero };
        private Object[] m_BufForSaveImageLock = new Object[4];
        public  MyCamera.MV_FRAME_OUT_INFO_EX[] m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX[4];

        MyCamera.cbOutputExdelegate cbImage;
        MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;
        private MyCamera[] m_pMyCamera;
        MyCamera.MV_CC_DEVICE_INFO[] m_pDeviceInfo;
        bool m_bGrabbing;
        int m_nCanOpenDeviceNum;        // ch:设备使用数量 | en:Used Device Number
        int m_nDevNum;        // ch:在线设备数量 | en:Online Device Number
        int[] m_nFrames;      // ch:帧数 | en:Frame Number
        bool m_bTimerFlag;     // ch:定时器开始计时标志位 | en:Timer Start Timing Flag Bit
        IntPtr[] m_hDisplayHandle;

        public byte[] currP_Data;
        public  byte[] currP_Data_01;
        public  byte[] currP_Data_02;
        public  byte[] currP_Data_03;

        public ushort currWidth;
        public ushort currHeight;


        public void MultipleParamInit()
        {
            m_pDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            m_bGrabbing = false;
            m_nCanOpenDeviceNum = 0;
            m_nDevNum = 0;
            m_pMyCamera = new MyCamera[4];//
            m_pDeviceInfo = new MyCamera.MV_CC_DEVICE_INFO[4];
            m_nFrames = new int[4];
            cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack);
            for (int i = 0; i < 4; ++i)
            {
                m_BufForSaveImageLock[i] = new Object();
            }//

            m_bTimerFlag = false;
            m_hDisplayHandle = new IntPtr[4];

            // ch: 初始化 SDK | en: Initialize SDK
            MyCamera.MV_CC_Initialize_NET();

            // ch: 枚举设备列表 | en: Enum Devices
            DeviceListAcq();
        }
        // ch:枚举设备 | en:Create Device List
        private void DeviceListAcq()
        {
            System.GC.Collect();
            int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
            if (0 != nRet)
            {
                richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ")+"Enumerate devices fail!\r\n";
                return;
            }
            //设备数量
            m_nDevNum = (int)m_pDeviceList.nDeviceNum;
            Console.WriteLine("在线相机数量： "+ m_nDevNum.ToString("d"));
            richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + "在线相机数量： " + m_nDevNum.ToString("d")+ "!\r\n";
        }
        // ch:取流回调函数 | en:Aquisition Callback Function
        private void ImageCallBack(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
        {
            Console.WriteLine("pFrameInfo.nFrameLen:   " + pFrameInfo.nFrameLen);
            Console.WriteLine("pFrameInfo.nWidth:   " + pFrameInfo.nWidth);
            Console.WriteLine("pFrameInfo.nHeight:   " + pFrameInfo.nHeight);
            Console.WriteLine("pFrameInfo.enPixelType:   " + pFrameInfo.enPixelType);

            
            //Console.WriteLine("pData:   " + Encoding.Default.GetBytes(Marshal.PtrToStringAnsi(pData)).Length);

            int nIndex = (int)pUser;
            Console.WriteLine("nIndex:   " + nIndex);

            switch (nIndex)
            {
                case 0:
                    currP_Data_01 = IntPtrToBytes(pData, (int)pFrameInfo.nFrameLen);
                    Console.WriteLine("pData01:   " + currP_Data_01.Length);
                    break;
                case 1:
                    currP_Data_02 = IntPtrToBytes(pData, (int)pFrameInfo.nFrameLen);
                    Console.WriteLine("pData02:   " + currP_Data_02.Length);
                    break;
                case 2:
                    currP_Data_03 = IntPtrToBytes(pData, (int)pFrameInfo.nFrameLen);
                    Console.WriteLine("pData03:   " + currP_Data_03.Length);
                    break;
            }
            currP_Data = IntPtrToBytes(pData, (int)pFrameInfo.nFrameLen);
            currWidth = pFrameInfo.nWidth;
            currHeight = pFrameInfo.nHeight;
            Console.WriteLine("pData: " + currP_Data.Length+ "  nWidth: " + currWidth + "  nHeight: " + currHeight);

            // ch:抓取的帧数 | en:Aquired Frame Number
            ++m_nFrames[nIndex];

            lock (m_BufForSaveImageLock[nIndex])
            {
                if (m_pSaveImageBuf[nIndex] == IntPtr.Zero || pFrameInfo.nFrameLen > m_nSaveImageBufSize[nIndex])
                {
                    if (m_pSaveImageBuf[nIndex] != IntPtr.Zero)
                    {
                        Marshal.Release(m_pSaveImageBuf[nIndex]);
                        m_pSaveImageBuf[nIndex] = IntPtr.Zero;
                    }

                    m_pSaveImageBuf[nIndex] = Marshal.AllocHGlobal((Int32)pFrameInfo.nFrameLen);
                    if (m_pSaveImageBuf[nIndex] == IntPtr.Zero)
                    {
                        return;
                    }
                    m_nSaveImageBufSize[nIndex] = pFrameInfo.nFrameLen;
                }

                m_stFrameInfo[nIndex] = pFrameInfo;
                CopyMemory(m_pSaveImageBuf[nIndex], pData, pFrameInfo.nFrameLen);
            }

            MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();
            stDisplayInfo.hWnd = m_hDisplayHandle[nIndex];
            stDisplayInfo.pData = pData;
            stDisplayInfo.nDataLen = pFrameInfo.nFrameLen;
            stDisplayInfo.nWidth = pFrameInfo.nWidth;
            stDisplayInfo.nHeight = pFrameInfo.nHeight;
            stDisplayInfo.enPixelType = pFrameInfo.enPixelType;

            m_pMyCamera[nIndex].MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);

            Console.WriteLine(IntPtrToBytes(stDisplayInfo.pData,(int)stDisplayInfo.nDataLen).Length);

            AlgorithmModule.ImageHandle();
            AlgorithmModule.RectPoints(m_hDisplayHandle[nIndex]);
            //pictureBoxes[nIndex].Image = AlgorithmModule.RectPoints(pictureBoxes[nIndex].Image);
        }
        byte[] IntPtrToBytes(IntPtr ptr, int length)
        {
            byte[] bytes = new byte[length];
            Marshal.Copy(ptr, bytes, 0, length);
            return bytes;
        }

        string[] CameraSerialNumber;
        // ch:初始化、打开相机 | en:Initialization and open devices
        public void OpenDevice()
        {
            CameraSerialNumber = new string[3];
            DeviceListAcq();
            if (m_nDevNum == 0)
                return;
            bool bOpened = false;
            // ch:判断输入格式是否正确 | en:Determine whether the input format is correct
            //try
            //{
            //    int.Parse(tbUseNum.Text);
            //}
            //catch
            //{
            //    richTextBox.Text += "Please enter correct format!\r\n";
            //    return;
            //}
            // ch:获取使用设备的数量 | en:Get Used Device Number  
            //int nCameraUsingNum = int.Parse(tbUseNum.Text);
            int nCameraUsingNum = m_nDevNum;
            // ch:参数检测 | en:Parameters inspection
            if (nCameraUsingNum <= 0)
            {
                //nCameraUsingNum = 1;
            }
            if (nCameraUsingNum > 4)
            {
                //nCameraUsingNum = 4;
            }

            for (int i = 0, j = 0; j < m_nDevNum; j++)
            {
                //ch:获取选择的设备信息 | en:Get Selected Device Information
                MyCamera.MV_CC_DEVICE_INFO device =
                    (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[j], typeof(MyCamera.MV_CC_DEVICE_INFO));

                string StrTemp = "";
                string strUserDefinedName = "";

                if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                {
                    MyCamera.MV_GIGE_DEVICE_INFO_EX gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO_EX)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO_EX));

                    if ((gigeInfo.chUserDefinedName.Length > 0) && (gigeInfo.chUserDefinedName[0] != '\0'))
                    {
                        if (MyCamera.IsTextUTF8(gigeInfo.chUserDefinedName))
                        {
                            strUserDefinedName = Encoding.UTF8.GetString(gigeInfo.chUserDefinedName).TrimEnd('\0');
                        }
                        else
                        {
                            strUserDefinedName = Encoding.Default.GetString(gigeInfo.chUserDefinedName).TrimEnd('\0');
                        }
                        StrTemp = "GEV: " + strUserDefinedName + " (" + gigeInfo.chSerialNumber + ")";
                    }
                    else
                    {
                        StrTemp = "GEV: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")";
                    }
                    CameraSerialNumber[i] = gigeInfo.chSerialNumber;
                }
                else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
                {
                    MyCamera.MV_USB3_DEVICE_INFO_EX usbInfo = (MyCamera.MV_USB3_DEVICE_INFO_EX)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO_EX));

                    if ((usbInfo.chUserDefinedName.Length > 0) && (usbInfo.chUserDefinedName[0] != '\0'))
                    {
                        if (MyCamera.IsTextUTF8(usbInfo.chUserDefinedName))
                        {
                            strUserDefinedName = Encoding.UTF8.GetString(usbInfo.chUserDefinedName).TrimEnd('\0');
                        }
                        else
                        {
                            strUserDefinedName = Encoding.Default.GetString(usbInfo.chUserDefinedName).TrimEnd('\0');
                        }

                        StrTemp = "U3V: " + strUserDefinedName + " (" + usbInfo.chSerialNumber + ")";
                    }
                    else
                    {
                        StrTemp = "U3V: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")";
                    }
                }

                //ch:打开设备 | en:Open Device
                if (null == m_pMyCamera[i])
                {
                    m_pMyCamera[i] = new MyCamera();
                    if (null == m_pMyCamera[i])
                    {
                        return;
                    }
                }

                int nRet = m_pMyCamera[i].MV_CC_CreateDevice_NET(ref device);
                if (MyCamera.MV_OK != nRet)
                {
                    return;
                }

                nRet = m_pMyCamera[i].MV_CC_OpenDevice_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("Open Device[{0}] failed! nRet=0x{1}\r\n", StrTemp, nRet.ToString("X"));
                    continue;
                }
                else
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("Open Device[{0}] success!\r\n", StrTemp);

                    m_nCanOpenDeviceNum++;
                    m_pDeviceInfo[i] = device;
                    // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
                    if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                    {
                        int nPacketSize = m_pMyCamera[i].MV_CC_GetOptimalPacketSize_NET();
                        if (nPacketSize > 0)
                        {
                            nRet = m_pMyCamera[i].MV_CC_SetIntValueEx_NET("GevSCPSPacketSize", nPacketSize);
                            if (nRet != MyCamera.MV_OK)
                            {
                                richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("Set Packet Size failed! nRet=0x{0}\r\n", nRet.ToString("X"));
                            }
                        }
                        else
                        {
                            richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("Get Packet Size failed! nRet=0x{0}\r\n", nPacketSize.ToString("X"));
                        }
                    }

                    m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
                    m_pMyCamera[i].MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)i);
                    bOpened = true;
                    if (m_nCanOpenDeviceNum == nCameraUsingNum)
                    {
                        break;
                    }
                    i++;
                }
            }

            // ch:只要有一台设备成功打开 | en:As long as there is a device successfully opened
            if (bOpened)
            {
                Console.WriteLine("使用相机个数： "+ m_nCanOpenDeviceNum.ToString());
                for (int i = 0; i < CameraSerialNumber.Length; i++)
                {
                    Console.WriteLine("SerialNumber: "+CameraSerialNumber[i]);
                }
                //tbUseNum.Text = m_nCanOpenDeviceNum.ToString();
                SetCtrlWhenOpen();
            }
        }
        //控件操作
        private void SetCtrlWhenOpen()
        {
            StartBtn.Enabled = false;
            StopBtn.Enabled = true;
            mainTriggerModeCB.Enabled = true;
        }
        // ch:关闭相机 | en:Close Device
        public void CloseDevice()
        {
            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                int nRet;

                nRet = m_pMyCamera[i].MV_CC_CloseDevice_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    return;
                }

                nRet = m_pMyCamera[i].MV_CC_DestroyDevice_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    return;
                }
            }

            //控件操作 ch: | en:Control Operation
            SetCtrlWhenClose();
            // ch:取流标志位清零 | en:Zero setting grabbing flag bit
            m_bGrabbing = false;
            // ch:重置成员变量 | en:Reset member variable
            ResetMember();
        }
        //控件操作                                                                                                                                                                                                                                                
        private void SetCtrlWhenClose()
        {
            StartBtn.Enabled = true;
            StopBtn.Enabled = false;
            mainTriggerModeCB.Checked = false;
            mainTriggerModeCB.Enabled = false;
        }

        public void ResetMember()
        {
            m_pDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            m_bGrabbing = false;
            m_nCanOpenDeviceNum = 0;
            m_nDevNum = 0;
            DeviceListAcq();
            m_nFrames = new int[4];
            cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack);
            m_bTimerFlag = false;
            m_hDisplayHandle = new IntPtr[4];
            m_pDeviceInfo = new MyCamera.MV_CC_DEVICE_INFO[4];
        }

        bool isContinuesMode;
        bool isTriggerMode;
        bool isSaveImg;
        bool isSoftTrigger;
        // ch:连续采集 | en:
        public void OpenContinuesMode()
        {
            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
            }
        }
        // ch:打开触发模式 | en:Open Trigger Mode
        public void OpenTriggerMode()
        {
            isSoftTrigger = mainTriggerModeCB.Checked;
            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);

                // ch:触发源选择:0 - Line0; | en:Trigger source select:0 - Line0;
                //           1 - Line1;
                //           2 - Line2;
                //           3 - Line3;
                //           4 - Counter;
                //           7 - Software;
                if (isSoftTrigger)
                {
                    m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
                }
                else
                {
                    m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
                }

            }
        } 
        //设为软触发
        public void ChangeSoftTrigger()
        {
            isSoftTrigger = mainTriggerModeCB.Checked;

            if (isSoftTrigger)
            {
                Console.WriteLine("isSoftTrigger: " + isSoftTrigger+ "  设为软触发");
                // ch:触发源设为软触发 | en:Set Trigger Source As Software
                for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
                {
                    m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
                }
            }
            else
            {
                Console.WriteLine("isSoftTrigger: " + isSoftTrigger + "  设为LINE0");
                for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
                {
                    m_pMyCamera[i].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
                }
            }
        }
        //软触发一次
        public void TriggerOnce()
        {
            int nRet;

            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                nRet = m_pMyCamera[i].MV_CC_SetCommandValue_NET("TriggerSoftware");
                if (MyCamera.MV_OK != nRet)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} Set software trigger failed! nRet=0x{1}\r\n", (i + 1).ToString(), nRet.ToString("X"));
                    
                    //AlgorithmModule.ImageHandle();
                    //pictureBoxes[i].Image = AlgorithmModule.RectPoints(pictureBoxes[i].Image);
                }
            }

        }
        public void TriggerOnce_SingleCamera(int index)
        {
            int nRet;

            nRet = m_pMyCamera[index].MV_CC_SetCommandValue_NET("TriggerSoftware");
            if (MyCamera.MV_OK != nRet)
            {
                richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} Set software trigger failed! nRet=0x{1}\r\n", (index + 1).ToString(), nRet.ToString("X"));
            }

            //AlgorithmModule.ImageHandle();
            //pictureBoxes[index].Image = AlgorithmModule.RectPoints(pictureBoxes[index].Image);
        }


        //开始抓取
        public void StartGrab()
        {
            int nRet;
            m_hDisplayHandle[0] = cameraPb_01.Handle;
            m_hDisplayHandle[1] = cameraPb_02.Handle;
            m_hDisplayHandle[2] = cameraPb_03.Handle;
            //m_hDisplayHandle[3] = pictureBox4.Handle;

            // ch:开始采集 | en:Start Grabbing
            for (int i = 0; i < m_nCanOpenDeviceNum; i++)
            {
                m_nFrames[i] = 0;
                m_stFrameInfo[i].nFrameLen = 0;//取流之前先清除帧长度
                m_stFrameInfo[i].enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;
                nRet = m_pMyCamera[i].MV_CC_StartGrabbing_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} Start Grabbing failed! nRet=0x{1}\r\n", (i + 1).ToString(), nRet.ToString("X"));
                }
            }

            //ch:开始计时  | en:Start Timing
            m_bTimerFlag = true;
            // ch:控件操作 | en:Control Operation
            SetCtrlWhenStartGrab();
            // ch:标志位置位true | en:Set Position Bit true
            m_bGrabbing = true;
        }
        private void SetCtrlWhenStartGrab()
        {
            saveAllImageBtn.Enabled = true;
            if (m_nCanOpenDeviceNum > 0)
                saveImgBtn01.Enabled = true;
            if (m_nCanOpenDeviceNum > 1)
                saveImgBtn02.Enabled = true;
            if (m_nCanOpenDeviceNum > 2)
                saveImgBtn03.Enabled = true;
        }
        //停止抓取 
        public void StopGrab()
        {
            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                m_pMyCamera[i].MV_CC_StopGrabbing_NET();
            }
            //ch:标志位设为false  | en:Set Flag Bit false
            m_bGrabbing = false;
            // ch:停止计时 | en:Stop Timing
            m_bTimerFlag = false;

            // ch:控件操作 | en:Control Operation
            SetCtrlWhenStopGrab();
        }
        private void SetCtrlWhenStopGrab()
        {
            saveAllImageBtn.Enabled = false;
            if (m_nCanOpenDeviceNum > 0)
                saveImgBtn01.Enabled = false;
            if (m_nCanOpenDeviceNum > 1)
                saveImgBtn02.Enabled = false;
            if (m_nCanOpenDeviceNum > 2)
                saveImgBtn03.Enabled = false;
        }

        //保存图片
        public void SaveImg()
        {
            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM();
                lock (m_BufForSaveImageLock[i])
                {
                    if (m_stFrameInfo[i].nFrameLen == 0)
                    {
                        richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} save image failed! No data!\r\n", (i + 1).ToString());
                        continue;
                    }
                    stSaveParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
                    stSaveParam.enPixelType = m_stFrameInfo[i].enPixelType;
                    stSaveParam.pData = m_pSaveImageBuf[i];
                    stSaveParam.nDataLen = m_stFrameInfo[i].nFrameLen;
                    stSaveParam.nHeight = m_stFrameInfo[i].nHeight;
                    stSaveParam.nWidth = m_stFrameInfo[i].nWidth;
                    stSaveParam.pImagePath = "Dev" + i.ToString() + "_Img_w" + stSaveParam.nWidth.ToString() + "_h" + stSaveParam.nHeight.ToString() + "_fn" + m_stFrameInfo[i].nFrameNum.ToString() +"_"+DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".bmp";
                    //stSaveParam.nQuality = 80;//存Jpeg时有效
                    int nRet = m_pMyCamera[i].MV_CC_SaveImageToFile_NET(ref stSaveParam);
                    if (MyCamera.MV_OK != nRet)
                    {
                        richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} save image failed! nRet=0x{1}\r\n", (i + 1).ToString(), nRet.ToString("X"));
                    }
                    else
                    {
                        richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} save image Succeed!\r\n", (i + 1).ToString());
                    }
                }
            }
        }
        public void SaveSingleImg(int index)
        {
            MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM();
            lock (m_BufForSaveImageLock[index])
            {
                if (m_stFrameInfo[index].nFrameLen == 0)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} save image failed! No data!\r\n", (index + 1).ToString());
                }
                stSaveParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;
                stSaveParam.enPixelType = m_stFrameInfo[index].enPixelType;
                stSaveParam.pData = m_pSaveImageBuf[index];
                stSaveParam.nDataLen = m_stFrameInfo[index].nFrameLen;
                stSaveParam.nHeight = m_stFrameInfo[index].nHeight;
                stSaveParam.nWidth = m_stFrameInfo[index].nWidth;
                stSaveParam.pImagePath = "Dev" + index.ToString() + "_Img_w" + stSaveParam.nWidth.ToString() + "_h" + stSaveParam.nHeight.ToString() + "_fn" + m_stFrameInfo[index].nFrameNum.ToString() + "_" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".bmp";
                //stSaveParam.nQuality = 80;//存Jpeg时有效
                int nRet = m_pMyCamera[index].MV_CC_SaveImageToFile_NET(ref stSaveParam);
                if (MyCamera.MV_OK != nRet)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} save image failed! nRet=0x{1}\r\n", (index + 1).ToString(), nRet.ToString("X"));
                }
                else
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} save image Succeed!\r\n", (index + 1).ToString());
                }
            }
        }

        //设置曝光时间和增益
        public void SetParam(string Exposure,string Gain)
        {
            try
            {
                float.Parse(Exposure);
                float.Parse(Gain);
            }
            catch
            {
                richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("Please Enter Correct Type.\r\n");
                return;
            }
            if (float.Parse(Exposure) < 0 || float.Parse(Gain) < 0)
            {
                richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("Set ExposureTime or Gain fail,Because ExposureTime or Gain less than zero.\r\n");
                return;
            }

            int nRet;
            for (int i = 0; i < m_nCanOpenDeviceNum; ++i)
            {
                bool bSuccess = true;
                m_pMyCamera[i].MV_CC_SetEnumValue_NET("ExposureAuto", 0);

                nRet = m_pMyCamera[i].MV_CC_SetFloatValue_NET("ExposureTime", float.Parse(Exposure));
                if (nRet != MyCamera.MV_OK)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} Set Exposure Time Failed! nRet=0x{1}\r\n", (i + 1).ToString(), nRet.ToString("X"));
                    bSuccess = false;
                }

                m_pMyCamera[i].MV_CC_SetEnumValue_NET("GainAuto", 0);
                nRet = m_pMyCamera[i].MV_CC_SetFloatValue_NET("Gain", float.Parse(Gain));
                if (nRet != MyCamera.MV_OK)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} Set Gain Failed! nRet=0x{1}\r\n", (i + 1).ToString(), nRet.ToString("X"));
                    bSuccess = false;
                }

                if (bSuccess)
                {
                    richTextBox.Text = richTextBox.Text + DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss ") + String.Format("No.{0} Set Parameters Succeed!\r\n", (i + 1).ToString());
                }
            }
        }

        // ch:获取丢帧数 | en:Get Throw Frame Number
        private string GetLostFrame(int nIndex)
        {
            MyCamera.MV_ALL_MATCH_INFO pstInfo = new MyCamera.MV_ALL_MATCH_INFO();
            if (m_pDeviceInfo[nIndex].nTLayerType == MyCamera.MV_GIGE_DEVICE)
            {
                MyCamera.MV_MATCH_INFO_NET_DETECT MV_NetInfo = new MyCamera.MV_MATCH_INFO_NET_DETECT();
                pstInfo.nInfoSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(MyCamera.MV_MATCH_INFO_NET_DETECT));
                pstInfo.nType = MyCamera.MV_MATCH_TYPE_NET_DETECT;
                int size = Marshal.SizeOf(MV_NetInfo);
                pstInfo.pInfo = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(MV_NetInfo, pstInfo.pInfo, false);

                m_pMyCamera[nIndex].MV_CC_GetAllMatchInfo_NET(ref pstInfo);
                MV_NetInfo = (MyCamera.MV_MATCH_INFO_NET_DETECT)Marshal.PtrToStructure(pstInfo.pInfo, typeof(MyCamera.MV_MATCH_INFO_NET_DETECT));

                string sTemp = MV_NetInfo.nLostFrameCount.ToString();
                Marshal.FreeHGlobal(pstInfo.pInfo);
                return sTemp;
            }
            else if (m_pDeviceInfo[nIndex].nTLayerType == MyCamera.MV_USB_DEVICE)
            {
                MyCamera.MV_MATCH_INFO_USB_DETECT MV_NetInfo = new MyCamera.MV_MATCH_INFO_USB_DETECT();
                pstInfo.nInfoSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(MyCamera.MV_MATCH_INFO_USB_DETECT));
                pstInfo.nType = MyCamera.MV_MATCH_TYPE_USB_DETECT;
                int size = Marshal.SizeOf(MV_NetInfo);
                pstInfo.pInfo = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(MV_NetInfo, pstInfo.pInfo, false);

                m_pMyCamera[nIndex].MV_CC_GetAllMatchInfo_NET(ref pstInfo);
                MV_NetInfo = (MyCamera.MV_MATCH_INFO_USB_DETECT)Marshal.PtrToStructure(pstInfo.pInfo, typeof(MyCamera.MV_MATCH_INFO_USB_DETECT));

                string sTemp = MV_NetInfo.nErrorFrameCount.ToString();
                Marshal.FreeHGlobal(pstInfo.pInfo);
                return sTemp;
            }
            else
            {
                return "0";
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (m_bTimerFlag)
            {
                if (m_nCanOpenDeviceNum > 0)
                {
                    Console.WriteLine("相机1采集帧数："+ m_nFrames[0].ToString());
                    Console.WriteLine("相机1丢帧数：" + GetLostFrame(0));
                }
                if (m_nCanOpenDeviceNum > 1)
                {
                    Console.WriteLine("相机2采集帧数：" + m_nFrames[1].ToString());
                    Console.WriteLine("相机2丢帧数：" + GetLostFrame(1));
                }
                if (m_nCanOpenDeviceNum > 2)
                {
                    Console.WriteLine("相机3采集帧数：" + m_nFrames[2].ToString());
                    Console.WriteLine("相机3丢帧数：" + GetLostFrame(2));
                }

            }
        }

        #endregion

        private void richTextBox_TextChanged(object sender, EventArgs e)
        {
            richTextBox.SelectionStart = richTextBox.Text.Length;
            richTextBox.ScrollToCaret();
        }

        private void richTextBox_DoubleClick(object sender, EventArgs e)
        {
            richTextBox.Clear();
        }




        private void mainTriggerOnceBtn_Click(object sender, EventArgs e)
        {
            TriggerOnce();
        }

        private void TriggerOnceBtn_01_Click(object sender, EventArgs e)
        {
            if (m_nCanOpenDeviceNum > 0)
                TriggerOnce_SingleCamera(0);
        }

        private void TriggerOnceBtn_02_Click(object sender, EventArgs e)
        {
            if (m_nCanOpenDeviceNum > 1)
                TriggerOnce_SingleCamera(1);
        }

        private void TriggerOnceBtn_03_Click(object sender, EventArgs e)
        {
            if (m_nCanOpenDeviceNum > 2)
                TriggerOnce_SingleCamera(2);
        }

        private void mainTriggerModeCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeSoftTrigger();
            if (mainTriggerModeCB.Checked)
            {
                mainTriggerOnceBtn.Enabled = true;
                TriggerOnceBtn_01.Enabled = true;
                TriggerOnceBtn_02.Enabled = true;
                TriggerOnceBtn_03.Enabled = true;
            }
            else
            {
                mainTriggerOnceBtn.Enabled = false;
                TriggerOnceBtn_01.Enabled = false;
                TriggerOnceBtn_02.Enabled = false;
                TriggerOnceBtn_03.Enabled = false;
            }

        }

        private void saveAllImageBtn_Click(object sender, EventArgs e)
        {
            SaveImg();
        }

        private void saveImgBtn01_Click(object sender, EventArgs e)
        {
            SaveSingleImg(0);
        }

        private void saveImgBtn02_Click(object sender, EventArgs e)
        {
            SaveSingleImg(1);
        }

        private void saveImgBtn03_Click(object sender, EventArgs e)
        {
            SaveSingleImg(2);
        }

        #region Motion
        public void MotionStart()
        {
            ContinuousMotion(0, 100, 10000, 0.5, 0.5, 100, 0.2, 1);
            ContinuousMotion(1, 100, 10000, 0.5, 0.5, 100, 0.2, 1);
        }
        public void MotionStop()
        {
            StopMotion(0, 0, 0.5);
            StopMotion(1, 0, 0.5);
        }


        //伺服始能
        private static void ServoStart()
        {
            if (LTDMC.dmc_read_sevon_pin(DMC300_Info.usCardId[0], 0) == 1)      //當讀取狀態為1時，當下始能未開啟
            {
                LTDMC.dmc_write_sevon_pin(DMC300_Info.usCardId[0], 0, 0);       //下達0時是開啟始能
            }
            else
            {
                LTDMC.dmc_write_sevon_pin(DMC300_Info.usCardId[0], 0, 1);       ////下達1時是關閉始能
            }
        }
        //正向连续运动
        public static void ContinuousMotion()
        {
            ushort usAxis = 0; //轴号
            double dStartVel = 100;           //起始速度
            double dMaxVel = 10000;             //运行速度
            double dTacc = 0.5;               //加速时间
            double dTdec = 0.5;               //减速时间
            double dStopVel = 100;            //停止速度
            double dSpara = 0.2;              //S段时间       
            ushort usDir = 1;               //运动方向

            LTDMC.dmc_set_profile(DMC300_Info.usCardId[0], usAxis, dStartVel, dMaxVel, dTacc, dTdec, dStopVel);//设置速度参数
            LTDMC.dmc_set_s_profile(DMC300_Info.usCardId[0], usAxis, 0, dSpara);                                    //设置S段速度参数
            LTDMC.dmc_vmove(DMC300_Info.usCardId[0], usAxis, usDir);
        }
        public static void ContinuousMotion(ushort usAxis, double dStartVel, double dMaxVel, double dTacc, double dTdec, double dStopVel, double dSpara, ushort usDir)
        {
            LTDMC.dmc_set_profile(DMC300_Info.usCardId[0], usAxis, dStartVel, dMaxVel, dTacc, dTdec, dStopVel);//设置速度参数
            LTDMC.dmc_set_s_profile(DMC300_Info.usCardId[0], usAxis, 0, dSpara);                                    //设置S段速度参数
            LTDMC.dmc_vmove(DMC300_Info.usCardId[0], usAxis, usDir);
        }
        //反向连续运动
        public static void BackContinuousMotion()
        {
            ushort usAxis = 0; //轴号
            double dStartVel = 100;           //起始速度
            double dMaxVel = 10000;             //运行速度
            double dTacc = 0.5;               //加速时间
            double dTdec = 0.5;               //减速时间
            double dStopVel = 100;            //停止速度
            double dSpara = 0.2;              //S段时间       
            ushort usDir = 0;               //运动方向

            LTDMC.dmc_set_profile(DMC300_Info.usCardId[0], usAxis, dStartVel, dMaxVel, dTacc, dTdec, dStopVel);//设置速度参数
            LTDMC.dmc_set_s_profile(DMC300_Info.usCardId[0], usAxis, 0, dSpara);                                    //设置S段速度参数
            LTDMC.dmc_vmove(DMC300_Info.usCardId[0], usAxis, usDir);
        }
        public static void BackContinuousMotion(ushort usAxis, double dStartVel, double dMaxVel, double dTacc, double dTdec, double dStopVel, double dSpara, ushort usDir)
        {
            LTDMC.dmc_set_profile(DMC300_Info.usCardId[0], usAxis, dStartVel, dMaxVel, dTacc, dTdec, dStopVel);//设置速度参数
            LTDMC.dmc_set_s_profile(DMC300_Info.usCardId[0], usAxis, 0, dSpara);                                    //设置S段速度参数
            LTDMC.dmc_vmove(DMC300_Info.usCardId[0], usAxis, usDir);
        }
        //停止运动
        public static void StopMotion()
        {
            ushort usAxis = 0;                             //轴号
            ushort usStopMode = 0;                                 //制动方式，0：减速停止，1：紧急停止
            double dTdec = Double.Parse("0.5");       //减速时间         
            LTDMC.dmc_set_dec_stop_time(DMC300_Info.usCardId[0], usAxis, dTdec);  //设置减速停止时间
            LTDMC.dmc_stop(DMC300_Info.usCardId[0], usAxis, usStopMode);
        }
        public static void StopMotion(ushort usAxis, ushort usStopMode, double dTdec)
        {
            LTDMC.dmc_set_dec_stop_time(DMC300_Info.usCardId[0], usAxis, dTdec);  //设置减速停止时间
            LTDMC.dmc_stop(DMC300_Info.usCardId[0], usAxis, usStopMode);
        }


        private void Axis1MoveBtn_Click(object sender, EventArgs e)
        {
            ContinuousMotion();
        }

        private void Axis1BackMoveBtn_Click(object sender, EventArgs e)
        {
            BackContinuousMotion();
        }

        private void Axis1StopMoveBtn_Click(object sender, EventArgs e)
        {
            StopMotion();
        }

        private void Axis2MoveBtn_Click(object sender, EventArgs e)
        {
            ContinuousMotion(1, 100, 10000, 0.5, 0.5, 100, 0.2, 1);
        }

        private void Axis2BackMoveBtn_Click(object sender, EventArgs e)
        {
            BackContinuousMotion(1, 100, 10000, 0.5, 0.5, 100, 0.2, 0);
        }

        private void Axis2StopMoveBtn_Click(object sender, EventArgs e)
        {
            StopMotion(1, 0, 0.5);
        }
        private void StateClear01Btn_Click(object sender, EventArgs e)
        {
            ushort usAxis = 0;                           //轴号
            int dPos = 0;                                     // 当前位置
            LTDMC.dmc_set_position(DMC300_Info.usCardId[0], usAxis, dPos); //设置指定轴的当前指令位置值歸零
            LTDMC.dmc_set_encoder(DMC300_Info.usCardId[0], usAxis, dPos);  //設置指定軸編碼器歸零
        }

        private void StateClear02Btn_Click(object sender, EventArgs e)
        {
            ushort usAxis = 1;                           //轴号
            int dPos = 0;                                     // 当前位置
            LTDMC.dmc_set_position(DMC300_Info.usCardId[0], usAxis, dPos); //设置指定轴的当前指令位置值歸零
            LTDMC.dmc_set_encoder(DMC300_Info.usCardId[0], usAxis, dPos);  //設置指定軸編碼器歸零
        }

        public static string currSpeed;
        public static string currLocation;
        public static string feedBack;
        public static string runState;
        //机构运行状态
        private void runStateTimer_Tick(object sender, EventArgs e)
        {
            ushort usAxis = 0;  //轴号
            double dCurrentVel = 0;     //速度
            UInt32 nCmdPos = 0;         //指令位置
            UInt32 nEnPos = 0;          //编码器反馈位置

            dCurrentVel = LTDMC.dmc_read_current_speed(DMC300_Info.usCardId[0], usAxis); // 读取轴当前速度
            currSpeed01Tb.Text = dCurrentVel.ToString();
            nCmdPos = LTDMC.dmc_get_position(DMC300_Info.usCardId[0], usAxis);           //读取指定轴指令位置值
            currLocation01Tb.Text = nCmdPos.ToString();
            nEnPos = LTDMC.dmc_get_encoder(DMC300_Info.usCardId[0], usAxis);             //读取指定轴的编码器反馈值
            feedBack01Tb.Text = nEnPos.ToString();

            if (LTDMC.dmc_check_done(DMC300_Info.usCardId[0], usAxis) == 0)                      //读取指定轴运动状态
            {
                runState01Tb.Text = "轴一运行中";
            }
            else
            {
                runState01Tb.Text = "轴一停止";
            }

            //isSaveImg = saveImgcB.Checked;

            ushort usAxis02 = 1;  //轴号
            double dCurrentVel02 = 0;     //速度
            UInt32 nCmdPos02 = 0;         //指令位置
            UInt32 nEnPos02 = 0;          //编码器反馈位置

            dCurrentVel02 = LTDMC.dmc_read_current_speed(DMC300_Info.usCardId[0], usAxis02); // 读取轴当前速度
            currSpeed02Tb.Text = dCurrentVel02.ToString();
            nCmdPos02 = LTDMC.dmc_get_position(DMC300_Info.usCardId[0], usAxis02);           //读取指定轴指令位置值
            currLocation02Tb.Text = nCmdPos02.ToString();
            nEnPos02 = LTDMC.dmc_get_encoder(DMC300_Info.usCardId[0], usAxis02);             //读取指定轴的编码器反馈值
            feedBack02Tb.Text = nEnPos02.ToString();

            if (LTDMC.dmc_check_done(DMC300_Info.usCardId[0], usAxis02) == 0)                      //读取指定轴运动状态
            {
                runState02Tb.Text = "轴二运行中";
            }
            else
            {
                runState02Tb.Text = "轴二停止";
            }


            //currSpeed01Tb.Text = LocationThread.dCurrentVel[0].ToString();
            //currLocation01Tb.Text = LocationThread.LocationCont[0].ToString();
            //feedBack01Tb.Text = LocationThread.EncoderCont[0].ToString();

            //currSpeed02Tb.Text = LocationThread.dCurrentVel[1].ToString();
            //currLocation02Tb.Text = LocationThread.LocationCont[1].ToString();
            //feedBack02Tb.Text = LocationThread.EncoderCont[1].ToString();
        }

        #endregion

        private void Sensor01_Click(object sender, EventArgs e)
        {
            TestDioThread.iTestDio_Step = 31;
            //CameraReceiveThread_02.device.Parameters.SetCommandValue("TriggerSoftware");
            
            //SensorStateConfig.isTrigger01 = true;
            //Console.WriteLine(SensorStateConfig.isTrigger01 );
            //Console.WriteLine(CameraTriggerTime_Config.CamearTriggerPause01);
            //Console.WriteLine(SensorStateConfig.isTrigger01 && !CameraTriggerTime_Config.CamearTriggerPause01);

        }

        private void Sensor02_Click(object sender, EventArgs e)
        {
            TestDioThread.iTestDio_Step = 32;
            //CameraReceiveThread_03.device.Parameters.SetCommandValue("TriggerSoftware");
            //SensorStateConfig.isTrigger02 = true;
        }

        private void cameraPb_01_Click(object sender, EventArgs e)
        {

        }

        private void cameraPb_03_Click(object sender, EventArgs e)
        {

        }
        public static ConcurrentQueue<Bitmap> DisplayQueue01 = new ConcurrentQueue<Bitmap>();
        public static ConcurrentQueue<Bitmap> DisplayQueue02 = new ConcurrentQueue<Bitmap>();
        public static ConcurrentQueue<Bitmap> DisplayQueue03 = new ConcurrentQueue<Bitmap>();

        private System.Windows.Forms.Timer displayUpdateTimer;


        private void InitializeDisplayTimer()
        {
            displayUpdateTimer = new System.Windows.Forms.Timer();
            displayUpdateTimer.Interval = 100; // 100毫秒更新一次
            displayUpdateTimer.Tick += UpdateDisplay;
            displayUpdateTimer.Start();
        }

        private void UpdateDisplay(object sender, EventArgs e)
        {
            // 更新工位1
            if (DisplayQueue01.TryDequeue(out Bitmap bmp1))
            {
                UpdatePictureBox(cameraPb_01, bmp1);
            }

            // 更新工位2
            if (DisplayQueue02.TryDequeue(out Bitmap bmp2))
            {
                UpdatePictureBox(cameraPb_02, bmp2);
            }

            // 更新工位3
            if (DisplayQueue03.TryDequeue(out Bitmap bmp3))
            {
                UpdatePictureBox(cameraPb_03, bmp3);
            }
        }

        private void UpdatePictureBox(PictureBox pictureBox, Bitmap newImage)
        {
            if (pictureBox.InvokeRequired)
            {
                pictureBox.Invoke(new Action<PictureBox, Bitmap>(UpdatePictureBox), pictureBox, newImage);
                return;
            }

            // 释放旧图像
            if (pictureBox.Image != null)
            {
                var oldImage = pictureBox.Image;
                pictureBox.Image = null;
                oldImage.Dispose();
            }

            pictureBox.Image = newImage;
        }
    }
}
